package org.obsidianrad.server.services.user.rolemanager;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.obsidianrad.server.services.obj2db.dao.GenericProxy;
import org.obsidianrad.utils.Constant.ObsidianOperations;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;

public class RoleManagerImpl extends RoleManager {

	private GrantedAuthority[] grantedAuthority = null;
	
	@Override
	public String constructRole(String typeClass, Object... params) {
		return ("ROLE_" + typeClass + "#" + params[0]).toUpperCase();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Map<String, String>> getDataForAuth(){
		Map<String, Map<String, String>> retval = new HashMap<String, Map<String,String>>();
		Map<String, GenericProxy> beansOfType = this.getProxies();
		if(beansOfType.size()>0){
			Set<String> keySet = beansOfType.keySet();			
			Iterator<String> iterator = keySet.iterator();
			while(iterator.hasNext()){
				// proxies.add(beansOfType.get(iterator.next()).getTypeClass());
				String typeClass = beansOfType.get(iterator.next()).getTypeClass();
				Map<String, String> subRoles = new HashMap<String, String>();
				for(ObsidianOperations op : ObsidianOperations.values()){
					String roleName = constructRole(typeClass, op);
					subRoles.put(op.toString(), roleName);
				}
				retval.put(typeClass, subRoles);
			}
		}
		return retval;
		
	}
	
	@Override
	public GrantedAuthority[] getGrantedAuthorities() {
		if(grantedAuthority != null){
			return grantedAuthority;
		}else{
			List<String> localRoles = this.getRoles();//new ArrayList<String>();
			GrantedAuthority[] retVal = new GrantedAuthority[localRoles.size()];
			int i=0;
			for(String role : localRoles){
				retVal[i++] = new GrantedAuthorityImpl(role);
			}
			grantedAuthority = retVal;
			return retVal;		
		}
	}

	@SuppressWarnings("unchecked")
	private List<String> getRoles() {
		Map<String, GenericProxy> beansOfType = this.getProxies();
		if(beansOfType.size()>0){
			List<String> roles = new ArrayList<String>();

			Set<String> keySet = beansOfType.keySet();			
			Iterator<String> iterator = keySet.iterator();
			while(iterator.hasNext()){
				GenericProxy next = beansOfType.get(iterator.next());
				List<String> rolesBySingleObject = getRolesBySingleObject(next);
				if(rolesBySingleObject.size()>0){
					roles.addAll(rolesBySingleObject);
				}
			}
			return roles;
		}

		return null;
	}

	@SuppressWarnings("unchecked")
	private List<String> getRolesBySingleObject(GenericProxy obj) {
		String typeClass = obj.getTypeClass();
		
		List<String> list = new ArrayList<String>();
		for(ObsidianOperations op : ObsidianOperations.values()){
			list.add( constructRole(typeClass, op) );
		}
		return list;
	}

}
